package com.pansoft.xbrl.xbrljson.reader.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pansoft.xbrl.xbrljson.config.model.XbrlJsonConfig;
import com.pansoft.xbrl.xbrljson.reader.XbrlReader;
import com.pansoft.xbrl.xbrljson.util.StringUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.ElementModifier;
import org.dom4j.io.SAXReader;

import java.util.HashSet;
import java.util.List;

/**
 * 基础的xbrl实例文档读取器
 * @author coolmayi
 * @create 2021/9/6
 */
public class BaseXbrlReader implements XbrlReader {

    public static HashSet<String> InvalidNodeSet = new HashSet<String>();

    static {
        InvalidNodeSet.add("schemaRef");
        InvalidNodeSet.add("context");
        InvalidNodeSet.add("unit");
    }

    public JSONObject readXbrlDataWithPath(String xbrlFilePath) throws Exception {

        XbrlJsonConfig configObject = null;
        Document document = null;
        JSONObject xbrlDataJsonObject = null;
        try {
            SAXReader saxReader = new SAXReader();
            document = saxReader.read(xbrlFilePath);
            xbrlDataJsonObject = this.readXbrlData(document);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return xbrlDataJsonObject;
    }

    public JSONObject readXbrlDataWithXml(String xmlValue) throws Exception {

        if (StringUtil.isBlank(xmlValue)) {
            return null;
        }

        XbrlJsonConfig configObject = null;
        Document document = null;
        JSONObject xbrlDataJsonObject = null;
        try {
            document = DocumentHelper.parseText(xmlValue);
            xbrlDataJsonObject = this.readXbrlData(document);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return xbrlDataJsonObject;
    }

    /**
     * 读取实例文档那个数据节点
     * @param doc
     * @return
     * @throws Exception
     */
    public JSONObject readXbrlData(Document doc) throws Exception {

        if (doc == null) {
            return null;
        }

        Element rootNode = doc.getRootElement();

        if (rootNode == null) {
            return null;
        }

        List<Element> itemList = rootNode.elements();

        if (itemList == null || itemList.size() == 0) {
            return null;
        }

        JSONObject dataObject = new JSONObject(true);

        String itemName = null;
        for (Element item : itemList) {
            itemName = item.getName();
            if (InvalidNodeSet.contains(itemName)) {
                continue;
            }
            // 处理实例文档节点
            this.processInstDataNode(item, dataObject);
        }

        return dataObject;
    }

    /**
     * 处理实例文档节点
     * @param item
     * @param parentObjectNode
     */
    private void processInstDataNode(Element item, JSONObject parentObjectNode) {

        if (item == null || parentObjectNode == null) {
            return ;
        }

        String nodeName = item.getNamespace().getPrefix() + ":" +item.getName();
        String nodeValue = item.getTextTrim();

        // 判断是否存在下级
        List<Element> childList = item.elements();
        if (childList != null && childList.size() > 0) {
            // 创建
            JSONArray compNode = (JSONArray)parentObjectNode.get(nodeName);
            if (compNode == null) {
                compNode = new JSONArray();
                parentObjectNode.put(nodeName, compNode);
            }
            JSONObject childNodeObject = new JSONObject(true);
            compNode.add(childNodeObject);

            for (Element child : childList) {
                this.processInstDataNode(child, childNodeObject);
            }
        } else {
            // 普通节点
            parentObjectNode.put(nodeName, nodeValue);
        }
    }
}























